#include <zenilib.h>
#include <time.h>
#include "Enemy.h"
#include "BrainSlug.h"
#include "Person.h"

using namespace std;

Enemy::Enemy(Vector2 pos)
{
	playertype = ENEMY;
	body = new Person(pos);
	brain = new BrainSlug(pos);
	brain->setColorFilter(0, "red");
	brain->setRot(-pi / 4);
	controlsPerson = true;
	body->setTexture(0, "");
	body->setTexture(1, "AgentStill");
	body->preTexture = "Agent";
	this->jumpVelocity = -400.0f;
	this->walkVelocity = 200.0f;
	InitializeControls(pos);
	weapon = new Weapon(type, this);
	setExtrasInPosition();
	timeElapsedPerformingAction = 0.0f;
}

void Enemy::determineAction(vector<Platform*> &platforms,
														vector<Player*> &npcs,
														Player* player,
														float timestep)
{
	bool breakingUp = false;
	timeElapsedPerformingAction += timestep;
	timeSinceLastShot += timestep;

	playerCanSee = (player->distanceFrom(this) < 1000);
	if(playerCanSee)
	{
		// Check if the Enemy hits a wall
		if((controls.left || controls.right) && 
			 this->previousPosition == this->getPos())
		{
			controls.jump = true;
		}

		// Check if the Enemy is bunching
		for(int i = 0; i < npcs.size(); i++)
		{
			if (!npcs[i]->dead()){
				if(this != npcs[i] && npcs[i]->playertype == ENEMY)
				{
					float dist = this->distanceFrom(npcs[i]);
					if(dist < this->getBody()->getScale().x)
					{
						breakingUp = true;
						if(getPos().x > npcs[i]->getPos().x)
						{
							controls.right = true;
							controls.left = false;
						}
						else
						{
							controls.left = true;
							controls.right = false;
						}
						break;
					}
				}
			}
		}

		//if(!player->controlsPerson && !breakingUp && 
		//	 timeElapsedPerformingAction > timeToPerformAction)
		//{
		//	controls.down = controls.fire =
		//		controls.left = controls.right = controls.up = false;
		//	timeElapsedPerformingAction = 0.0f;

		//	timeToPerformAction = 1.0f;
		//	if(getPos().x < player->getPos().x)
		//	{
		//		controls.right = true;
		//		controls.left = false;
		//	}
		//	else
		//	{
		//		controls.left = true;
		//		controls.right = false;
		//	}

		//	if(player->getPos().y + 200 < getPos().y)
		//		controls.jump = true;
		//}
		if(!breakingUp)
		{
			// If the enemy can shoot the person then shoot, and run in random direction
			if(timeSinceLastShot > 1.0f && getPos().y > player->getPos().y - 20 &&
				 getPos().y < player->getPos().y + 20 && 
				 !Collision::objectsIntersect(player->getBody(),getBody()))
			{
				timeSinceLastShot = 0.0f;
				if(getPos().x < player->getPos().x)
				{
					body->setFlipped(false);
					this->weapon->setFlipped(false);
				}
				else
				{
					body->setFlipped(true);
					this->weapon->setFlipped(true);
				}
				controls.fire = true;
				
				timeElapsedPerformingAction = 0.0f;
				timeToPerformAction = 1.0f;
				int action = rand() % 2;
				if(action == 0)
				{
					controls.left = true;
					controls.right = false;
				}
				else
				{
					controls.right = true;
					controls.left = false;
				}
			}

			if(timeElapsedPerformingAction > timeToPerformAction)
			{
				controls.down = controls.fire =
					controls.left = controls.right = controls.up = false;
				timeElapsedPerformingAction = 0.0f;
				
				// if the player is above find the best way to get up to the player
				if(getPos().y > player->getPos().y)
				{
					if(player->getBody()->grounded())
					{
						GameObject* playerPlatform = player->getBody()->platform;
						// if able to jump on players platform move till it's not under it and jump
						if(canJumpOnPlatform(playerPlatform))
						{
							float toJumpXPosLeft = playerPlatform->getPos().x - 
																		 playerPlatform->getScale().x/2 - 
																		 body->getScale().x/2;
							float toJumpXPosRight = playerPlatform->getPos().x +
																			playerPlatform->getScale().x/2 +
																			body->getScale().x/2;

							if(getPos().x < playerPlatform->getPos().x && 
								 getPos().x > toJumpXPosLeft)
							{
								timeToPerformAction = (getPos().x - toJumpXPosLeft) / this->walkVelocity;
								controls.left = true;
							}
							else if(getPos().x >= playerPlatform->getPos().x && 
											getPos().x < toJumpXPosRight)
							{
								timeToPerformAction = (toJumpXPosRight - getPos().x) / this->walkVelocity;
								controls.right = true;
							}
							else if((getPos().x <= toJumpXPosLeft && getPos().x > toJumpXPosLeft - 10) ||
											(getPos().x >= toJumpXPosRight && getPos().x < toJumpXPosRight + 10))
							{
								timeToPerformAction = -this->jumpVelocity / this->body->getAccel().y;
								controls.jump = true;
							}
							else if(getPos().x < toJumpXPosLeft)
							{
								timeToPerformAction = (toJumpXPosLeft - getPos().x) / this->walkVelocity;
								controls.right = true;
							}
							else if(getPos().x > toJumpXPosRight)
							{
								timeToPerformAction = (getPos().x - toJumpXPosRight) / this->walkVelocity;
								controls.left = true;
							}
							else {}
						}
						// search for closest platform to jump onto
						else {}
					}
					else
					{
						// Jump and move toward
						timeToPerformAction = 1.0f;
						if(body->grounded())
							controls.jump = true;

						if(getPos().x < player->getPos().x)
						{
							controls.right = true;
							controls.left = false;
						}
						else
						{
							controls.left = true;
							controls.right = false;
						}
					}
				}
				// if the player is below find the best way to get down
				else
				{
					timeToPerformAction = 1.0f;
					if(getPos().x < player->getPos().x)
					{
						controls.right = true;
						controls.left = false;
					}
					else
					{
						controls.left = true;
						controls.right = false;
					}
				}
			}
		}
		else {}
	}
	else {}
}